package com.example.tester.service;

import com.example.tester.entity.Student;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;

/**
 * @author lzh
 * @date 2019/9/6 - 16:47
 */

/**
 * 在这里@CacheConfig(cacheNames = "student")
 * 配置了该数据访问对象中返回的内容将存储于名为student的缓存对象中，
 * 我们也可以不使用该注解，直接通过@Cacheable自己配置缓存集的名字来定义
 */
@CacheConfig(cacheNames = "student")
public interface IStudentService {

    /**
     * @Cacheable   先查询redis,没查到执行查询SQL,并将结果保存到redis
     * @CachePut     执行SQL插入的同时 将方法的返回值放到redis缓存中
     * @CacheEvict    执行SQL删除的同时删除redis缓存
     * @Caching     可通过@Caching注解组合多个注解策略在一个方法上
     */



    /**
     * @CachePut
     * 将方法的返回值放到redis缓存中
     * @param student
     * @return
     */
    @CachePut(key = "#p0.sno")
    Student  addStudent(Student student);


    /**
     * @CachePut
     * 配置于函数上，能够根据参数定义条件来进行缓存，其缓存的是方法的返回值
     * 它每次都会真实调用函数，所以主要用于数据新增和修改操作上
     * @param student
     * @return
     */
    @CachePut(key = "#p0.sno")
    Student update(Student student);


    /**
     * @CacheEvict
     * 配置于函数上，通常用在删除方法上，用来从缓存中移除相应数据
     * allEntries：非必需，默认为false。当为true时，会移除所有数据
     * beforeInvocation：非必需，默认为false，会在调用方法之后移除数据。当为true时，会在调用方法之前移除数据
     * @param sno
     */
    @CacheEvict(key = "#p0", allEntries = true)
    void deleteStudentBySno(Integer sno);



    /**
     * @Cacheable
     * 配置了queryStudentBySno函数的返回值将被加入缓存。
     * 同时在查询时，会先从缓存中获取，若不存在才再发起对数据库的访问
     *
     * key 属性和keyGenerator属性只能二选一
     * @Cacheable(key = "#p0")：使用函数第一个参数作为缓存的key值
     * key：缓存对象存储在Map集合中的key值，非必需，缺省按照函数的所有参数组合作为key值
     * @param sno
     * @return
     */
    @Cacheable(key = "#p0")
//    使用RedisConfig中定义的keyGenerator
//    @Cacheable(keyGenerator = "keyGenerator")
    Student queryStudentBySno(Integer sno);



}
